package com.yeyaomai.dksns.flowis.quartz;

import java.text.ParseException;
import java.util.Date;
import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.data.mongodb.core.mapreduce.GroupByResults;
import org.springframework.data.mongodb.core.query.Criteria;
import com.yeyaomai.dksns.flowis.dao.DetailDao;
import com.yeyaomai.dksns.flowis.dao.MongoDBBasicDao;
import com.yeyaomai.dksns.flowis.dao.BrowserDao;
import com.yeyaomai.dksns.flowis.domain.Browser;
import com.yeyaomai.dksns.flowis.domain.flowisdetail.FlowisStatDetailDTO;
import com.yeyaomai.dksns.flowis.util.CollectionNames;
import com.yeyaomai.dksns.flowis.util.Globals;

public class BrowserExecutor extends MongoDBBasicDao<Browser>{

	@Resource
	private DetailDao detailDao;

	@Resource
	private BrowserDao browserDao;

	final Logger logger = Logger.getLogger("quartz");

	public void saveBrowser() throws ParseException {
		Date date = new Date();
		Date dates = new Date(date.getTime() - 1 * 3600 * 1000);
		String formDate = Globals.FORMAT_TYPE_A.format(dates);
		String toDate = Globals.FORMAT_TYPE_A.format(date);
		if (formDate.equals(toDate)) {
			toDate = Globals.FORMAT_TYPE_A.format(new Date(
					Globals.FORMAT_TYPE_A.parse(toDate).getTime() + 1 * 24
							* 3600 * 1000));
		}
		browserDao.delBrowserByDate(formDate);
		GroupByResults<FlowisStatDetailDTO> result = this.getVisitCountByTime(
				formDate, toDate);
		for (FlowisStatDetailDTO engine : result) {
			
				Browser browser = new Browser();
				browser.setReferDate(Globals.FORMAT_TYPE_A
						.parse(Globals.FORMAT_TYPE_A.format(dates)));
				if(null != engine.getBrowser())
				{
				browser.setBrowserName(engine.getBrowser());
				}
				else
				{
					browser.setBrowserName("其它");	
				}
				browser.setVisitCount(engine.getVisitCount());
				Integer uniqueCount = this.getUVByTime(formDate, toDate,
						engine.getBrowser());
				browser.setUniqueHost(uniqueCount);
				Integer ip = this.getIpByTime(formDate, toDate,
						engine.getBrowser());
				browser.setIp(ip);
				Integer newuniqueHost = this.getNewUVByTime(formDate, toDate,
						engine.getBrowser());
				browser.setNewUniqueHost(newuniqueHost);
				browser.setAvgStopTime(this.getAvgStopTime(formDate, toDate,
						engine.getBrowser()));
				logger.info(date+"running saveVisit 浏览器："+engine.getBrowser()+"ip数"+ip+"PV数"+engine.getVisitCount()+"独立访客:"+uniqueCount+"新独立访客:"+newuniqueHost);
				browserDao.addBrowser(browser);
		}
		logger.info("#############################浏览器定时任务执行添加完毕######################");
	}

	/**
	 * 按浏览器统计访问次数
	 */
	private GroupByResults<FlowisStatDetailDTO> getVisitCountByTime(
			String fromTrendDay, String toTrendDay) {

		String mapFunction = "{ visitCount: 0}";
		String reduceFunction = "function(doc, prev) {prev.visitCount+=1}";
		Criteria criteria = Criteria.where("access_date").gte(fromTrendDay)
				.lt(toTrendDay);
		GroupByResults<FlowisStatDetailDTO> result = detailDao.group(criteria,
				CollectionNames.BROWSER, mapFunction, reduceFunction,
				FlowisStatDetailDTO.class);
		return result;
	}

	/**
	 * 定时任务处理UV
	 */
	private int getUVByTime(String formDate, String toDate, String browserName) {
		String mapFunction = "{ visitCount: 0}";
		String reduceFunction = "function(doc, prev) {prev.visitCount+=1}";
		Criteria criteria = Criteria.where("access_date").gte(formDate)
				.lt(toDate).and("browser").is(browserName);
		int uvcount = detailDao.group(criteria, CollectionNames.COOKIEID,
				mapFunction, reduceFunction, FlowisStatDetailDTO.class)
				.getKeys();
		return uvcount;
	}

	/**
	 * 定时任务处理IP
	 */
	private int getIpByTime(String formDate, String toDate, String browserName) {
		String mapFunction = "{ip: 0}";
		String reduceFunction = "function(doc, prev) {prev.ip+=1}";
		Criteria criteria = Criteria.where("access_date").gte(formDate)
				.lt(toDate).and("browser").is(browserName);
		int ipcount = detailDao.group(criteria, CollectionNames.IP,
				mapFunction, reduceFunction, FlowisStatDetailDTO.class)
				.getKeys();
		return ipcount;
	}

	/**
	 * 定时任务处理newuv
	 */
	private int getNewUVByTime(String formDate, String toDate,
			String browserName) {
		int newuvcount = 0;
		String mapFunction = "{cookieId: 0}";
		String reduceFunction = "function(doc, prev) {prev.cookieId+=1}";
		Criteria criteria = Criteria.where("access_date").gte(formDate)
				.lt(toDate).and("browser").is(browserName)
				.and("visitCount").is(1);
		newuvcount = detailDao.group(criteria, CollectionNames.COOKIEID,
				mapFunction, reduceFunction, FlowisStatDetailDTO.class)
				.getKeys();
		return newuvcount;
	}
	
	/**
	 * 获取平均停留时间
	 * 
	 * @param formDate开始时间
	 * @param toDate结束时间
	 * @param browserName浏览器名称
	 * @return
	 */
	private Long getAvgStopTime(String formDate, String toDate,
			String browserName) {
		String mapFunction = "{ visitCount: 0}";
		String reduceFunction = "function(doc, prev) {prev.visitCount+=1}";
		Criteria criteria = Criteria.where("access_date").gte(formDate)
				.lt(toDate).and("browser").is(browserName);
		GroupByResults<FlowisStatDetailDTO> result = detailDao.group(criteria,
				CollectionNames.STOPTIME, mapFunction, reduceFunction,
				FlowisStatDetailDTO.class);
		Long count = 0L;
		for (FlowisStatDetailDTO engine : result) {
			if (engine.getStoptime() > 0) {
				count += engine.getStoptime() * engine.getVisitCount();
			}
		}
		return count;
	}
}
